package com.liu.project.config;


import com.liu.project.pojo.LoginUser;
import com.liu.project.pojo.SysRole;
import com.liu.project.utils.JwtUtils;
import com.liu.project.utils.Message;
import com.liu.project.utils.RedisUtil;
import com.liu.project.utils.ResponseUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.weaver.patterns.IToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @program: project
 * @description: security处理器
 * @author: 86187
 * @create: 2022-01-16 13:24
 **/


@Configuration
public class SecurityHandlerConfig {


    @Autowired
     JwtUtils jwtUtils;

    @Autowired
     RedisUtil redisUtil;


    //获取表单提交的用户名和密码

/*
* 登录成功
* 返回Token
* */
    @Bean
    public AuthenticationSuccessHandler loginSuccessHandler(){
        return new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                LoginUser principal = (LoginUser)authentication.getPrincipal();

                // 生成JWT，并放置到请求头中
                System.out.println("principal.getUsername()==>"+principal.getUsername());
                String jwt =  jwtUtils.createToken(principal,false);
                principal.setPassword(null);
                String token = jwtUtils.TOKEN_PREFIX + jwt;

               // response.setHeader(jwtUtils.TOKEN_HEADER,token);
                //存入redis
                redisUtil.set("user:"+principal.getUsername(),principal,jwtUtils.EXPIRATION);

                LoginUser o =(LoginUser) redisUtil.get("user:"+principal.getUsername());
                System.out.println("Success==>"+o);
                System.out.println(" HttpStatus.OK.value():"+ HttpStatus.OK.value());
                ResponseUtil.responseJson(response, HttpStatus.OK.value(),token);
            }
        };
    }



//  登录失败
@Bean
    public AuthenticationFailureHandler loginFailureHandler(){
        return new AuthenticationFailureHandler() {
            @Override
            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
                String msg = null;
                if (exception instanceof BadCredentialsException){
                    msg="密码错误";
                }else {
                    msg=exception.getMessage();
                }
                System.out.println("HttpStatus.UNAUTHORIZED.value():"+HttpStatus.UNAUTHORIZED.value());
                ResponseUtil.responseJson(response,HttpStatus.UNAUTHORIZED.value(),msg);

            }
        };
}
//    未登录，返回401
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint(){
        return new AuthenticationEntryPoint() {
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                System.out.println("无凭证");
                System.out.println("HttpStatus.UNAUTHORIZED.value():"+HttpStatus.UNAUTHORIZED.value());
                ResponseUtil.responseJson(response,HttpStatus.UNAUTHORIZED.value(),"请先登录");
        }
        };
    }
//    退出
    @Bean
    public LogoutSuccessHandler logoutSuccessHandler(){
        return new LogoutSuccessHandler() {
            @Override
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                if (authentication !=null){
                    new SecurityContextLogoutHandler().logout(request,response,authentication);
                }

                String token = request.getHeader(jwtUtils.TOKEN_HEADER);
                //去除bearer
                token = StringUtils.substring(token, JwtUtils.TOKEN_PREFIX.length());

                if (token !=null){
                    //移除
                    String username = jwtUtils.getUsername(token);
                    redisUtil.del("user:"+username);
                }
                ResponseUtil.responseJson(response,HttpStatus.OK.value(),"退出成功");
            }
        };
    }

//    无权访问 403
    @Bean
    public AccessDeniedHandler accessDeniedHandler(){
        return new AccessDeniedHandler() {
            @Override
            public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
                ResponseUtil.responseJson(response,HttpStatus.FORBIDDEN.value(),accessDeniedException.getMessage());
            }
        };
    }

}
